import json
import math
import os
import random
import pandas as pd
from feed_stats_missing_symbol_checker import check_missing_symbols
from glob import glob
from util import format_mea, to_snake_mea, get_symbol_group,load_from_db,git_root_path


def create_check_df(machine, mea, symbol_list):
    symbols_info = []
    for symbol in symbol_list:
        symbol_info = {
            'symbol': symbol,
            'mea': mea,
            'machine': machine
        }
        symbols_info.append(symbol_info)
    df_symbols_info = pd.DataFrame(symbols_info)
    return df_symbols_info

def load_from_parameter(machine, mea, check_list):
    mea = format_mea(mea)
    if len(check_list[0]) == 1:
        # check list is groups
        symbol_list = get_symbol_list_from_group(mea, check_list)
    else:
        symbol_list = check_list
    return create_check_df(machine, mea, symbol_list)


def get_symbol_list_from_group(mea, group_list):
    symbol_list = []
    mea = to_snake_mea(mea)
    symbol_groups = get_symbol_group()
    for group in group_list:
        symbol_list.extend(symbol_groups[mea][group])
    return symbol_list


def get_group_from_symbol_list(mea, symbol_list):
    group_list = set()
    mea = to_snake_mea(mea)
    symbol_groups = get_symbol_group()
    for group in symbol_groups[mea]:
        for symbol in symbol_list:
            if symbol in symbol_groups[mea][group]:
                group_list.add(group)
                break
    return list(group_list)


def generate_script(date, symbols_info, no_fast_feed_data):
    print('')
    print('+'*15+'script'+'+'*15)
    issue_symbol_list = symbols_info.iloc[list(no_fast_feed_data)]
    for machine in set(issue_symbol_list['machine']):
        for mea in set(issue_symbol_list[issue_symbol_list['machine'] == machine]['mea']):
            issue_symbol_current_mea = list(issue_symbol_list[(issue_symbol_list['machine'] == machine) & (issue_symbol_list['mea'] == mea)]['symbol'])
            issue_symbol_group = get_group_from_symbol_list(mea,issue_symbol_current_mea)
            if len(issue_symbol_group) == 0:
                print('%s : %s are already removed' % (mea,issue_symbol_current_mea))
                return
            raw_feed_dump_script(date, machine, mea, issue_symbol_group)
            print('-'*15)
            fast_feed_generate_script(date, machine, mea, issue_symbol_group)
            print('*'*30)


def raw_feed_file_path(date, machine, mea, group):
    raw_feed_data_path = '/remote/iosg/coin/data/flow/%s/%s/%s/'
    mea = to_snake_mea(mea)
    raw_feed_path = os.path.join(raw_feed_data_path % (
        machine, date, mea), '*_%s[1-2]*' % group)
    file_path_list = glob(raw_feed_path)
    if (len(file_path_list)>0):
        num = random.randrange(len(file_path_list))
        return file_path_list[num]
    return ['No Such Path']


def raw_feed_dump_script(date, machine, mea, group_list):
    oriocat_cmd = "oriocat -h --record=topic %s > ~/tmp/%s_%s_%s.dump"
    file_path_list = []
    for group in group_list:
        file_path_list.append(raw_feed_file_path(date, machine, mea, group))
    for n in range(len(file_path_list)):
        print(oriocat_cmd % (file_path_list[n], date,mea, group_list[n])) 
        print('')


def cal_slurm_config(mea, group_list):
    symbol_num = len(group_list)
    if symbol_num > 200:
        return ['16', '200']
    return [str(math.ceil(symbol_num/12)), str(symbol_num), ]


def fast_feed_generate_script(date, machine, mea, group_list):
    # slurm_config = cal_slurm_config(mea, group_list)
    group_config = ','.join(group_list)
    cmd = './pyrunner coin/support/feed_tool/feed_cache/app/coin2_fast_feed_runner.py --trading_date=%s --arbitration=1 --worker=1 --script_only=False --machine="%s" --mea="%s" --group="%s" --sbatch_args="-n%s --mem-per-cpu=1G --job-name=coin2_fastfeed --hint=multithread --priority=TOP --wait"'
    print(cmd % (date, machine, mea, group_config,len(group_list)))

def generate_with_check(date,machine, mea, check_list):
    symbols_info = load_from_parameter(machine, mea, check_list)
    no_fast_feed_data = check_missing_symbols(date, symbols_info)
    # symbols_info["trading_date"] = date
    # return symbols_info.iloc[list(no_fast_feed_data)]
    if len(no_fast_feed_data) == 0:
        print('No data need to generate script')
    generate_script(date, symbols_info, no_fast_feed_data)

def generate_through_db(date):
    symbols_info = load_from_db(date)
    no_fast_feed_data = check_missing_symbols(date, symbols_info, True)
    if len(no_fast_feed_data) == 0:
        print('No data need to generate script')
    generate_script(date, symbols_info, no_fast_feed_data)

def generate_directly(date,machine, mea, check_list):
    symbols_info = load_from_parameter(machine, mea, check_list)
    generate_script(date, symbols_info, set(range(len(symbols_info))))

def check_10ap_status(date):
    with open(f'{git_root_path}/data/coin2/feed/ops/feed-writer/feed-10.ap-northeast-1.aws.json','r') as f:
        config = json.load(f)
    symbols_info = None
    for mea, mea_config in config["feed"]["exchanges"].items():
        if '_split_channel' in mea :
            continue
        if symbols_info is not None:
            symbols_info = pd.concat([symbols_info,create_check_df('feed-10.ap-northeast-1.aws',mea,mea_config['products']['norms'])])
        else:
            symbols_info = create_check_df('feed-10.ap-northeast-1.aws',mea,mea_config['products']['norms'])
    symbols_info.reset_index(inplace=True)
    no_fast_feed_data = check_missing_symbols(date, symbols_info, True)
    generate_script(date, symbols_info, no_fast_feed_data)
    

##usage##
# generate_with_check('20230801', 'feed-05.ap-northeast-1.aws','futures_bybit_v3-linear',  ["a", "b", "c", "d", "e", "f", "g", ])
# generate_directly('20230401', 'feed-05.ap-northeast-1.aws','Futures.Binance.v1',  ["a"])
# check_10ap_status('20230512')
# generate_through_db('20230605')

generate_directly('20230701','feed-05.cn-hongkong.aliyun','futures_bybit_v3-linear',  ['a'])







